#include <elapsedMillis.h>
#include <SoftwareSerial.h>
const int IR1 = 2; 
const int HALL1=3;
int bluepin = 5; 
int greenpin =6;
int redpin =9;
unsigned int start_interval = 3000;
unsigned int card_interval = 5000;
unsigned int leave_interval = 3000;
elapsedMillis timeElapsed;
elapsedMillis timeElapsedfail;
elapsedMillis timeElapsedsuccess;
boolean fail=false;
boolean checkingIR=false;
boolean success=false;
boolean debug=true;
boolean bike_ready = false;
boolean timeout=false;

boolean isreach=false;
int HALL_AMOUNT=0;
int val=0;
SoftwareSerial mySerial(10,11); 
void setup() {  
  pinMode(redpin, OUTPUT);
  pinMode(bluepin, OUTPUT);
  pinMode(greenpin, OUTPUT);
  pinMode(IR1, INPUT); 
  pinMode(HALL1, INPUT);  
  Serial.begin(9600);
  mySerial.begin(38400);
  attachInterrupt(1, hall,FALLING);
}
void hall()
{
    //INTERRUPT FOR HALL EFFECT
    //Serial.print("interrupt");
    HALL_AMOUNT+=1;
}
void reset(){
    
}
void loop() {
  if (mySerial.available() > 0) {
     char ch = mySerial.read();
     if (ch == 'T') {
         //Serial.print("TIMEOUT");
         timeout=true;
     }
  }
  
  if(digitalRead(IR1)==LOW && bike_ready==false){
     if (timeElapsed > start_interval){  
     bike_ready=true;
     mySerial.print("S");
     Serial.print("Start");
     timeElapsed = 0;
     }
  }
  //CARD OUT ACTION
  //IF TIME IS OUT THEN CHECK IF REACH 40 STEPS OR OTHER CONDITION
  if(timeout && isreach){
    //RELAY FOR 2 SEC
    if (timeElapsed > card_interval ){  
      mySerial.print("F");
      
      timeElapsed = 0;
      analogWrite(redpin,45);
      analogWrite( bluepin, 51);
      analogWrite(greenpin, 65);
     }
  }
  //IF BIKE READY CHECK FOR HALL EFFECT
  if(bike_ready==true && !timeout){
    if(HALL_AMOUNT==14){
      mySerial.print("A");
      //Serial.print("A");
      //BLUE
      analogWrite(redpin,0);
      analogWrite(bluepin, 255);
      analogWrite(greenpin, 0);
      
    }
    if(HALL_AMOUNT==20){
      mySerial.print("B");
      //Serial.print("B");
      //RED
      analogWrite(redpin,255);
      analogWrite( bluepin, 0);
      analogWrite(greenpin, 0);
    }
    
    if(HALL_AMOUNT==26){
      mySerial.print("C");
      //Serial.print("C");
      //GREEN
      analogWrite(redpin,0);
      analogWrite( bluepin, 0);
      analogWrite(greenpin, 255);
    }
    
    if(HALL_AMOUNT==32){
      mySerial.print("D");
      //Serial.print("D");
      isreach=true;
      analogWrite(redpin,255);
      analogWrite( bluepin, 51);
      analogWrite(greenpin, 255);
   }
   //if(debug){
       Serial.print("hallamount");
       Serial.println(HALL_AMOUNT);
   //}
  }
  //////////////////////////////
  /*FAILURE CHECK OR END CHECK*/
  //IF PEOPLE LEAVE BIKE WITHOUT TIMEOUT CHECK FOR 5SEC
  if(digitalRead(IR1)==HIGH && bike_ready==true && !timeout && !checkingIR){
   fail=true;
   checkingIR=true;
   timeElapsedfail=0;
  }
  if(digitalRead(IR1)==LOW && checkingIR){
    checkingIR=false;
    fail=false;
    success=false;
    
  }
  //IF PEOPLE LEAVE BIKE WITH TIMEOUT CHECK FOR 5SEC
  if(digitalRead(IR1)==HIGH && bike_ready==true && timeout && !checkingIR){
    success=true;
    
    timeElapsedsuccess=0;
    checkingIR=true;
  }
  //CHECK ELAPSEDTIME
  if(fail){
    Serial.print(timeElapsedfail);
    if (timeElapsedfail>leave_interval){
     Serial.print("reset");
     timeElapsed=0;
    timeElapsedfail=0;
    timeElapsedsuccess=0;
    fail=false;
    success=false;
    debug=true;
    bike_ready = false;
    timeout=false;
    
    isreach=false;
    HALL_AMOUNT=0;
    Serial.print("reset");
    analogWrite(redpin,0);
    analogWrite( bluepin,0);
    analogWrite(greenpin,0);
    mySerial.print("R"); 
    }
  }
  if(success){
    if (timeElapsedsuccess>leave_interval){
     timeElapsed=0;
    timeElapsedfail=0;
    timeElapsedsuccess=0;
    fail=false;
    success=false;
    debug=true;
    bike_ready = false;
    timeout=false;
    
    isreach=false;
    HALL_AMOUNT=0;
    Serial.print("reset");
    analogWrite(redpin,0);
    analogWrite( bluepin,0);
    analogWrite(greenpin,0);
    mySerial.print("R"); 
    }
  }
  delay(100);  
}
